import json

from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import JsonResponse
from django.shortcuts import render
from django.utils import timezone
from django.views import View
from django_redis import get_redis_connection
from rest_framework import status

from goods.models import SKU
from orders.models import OrderInfo, OrderGoods
from users.models import Address


class OrderSettlementView(LoginRequiredMixin, View):
    def get(self, request):
        user = request.user
        addresses = user.addresses.all()

        redis_client = get_redis_connection('carts')
        selected_skus = redis_client.smembers('selected_%s' % user.id)

        sku_list = []
        total_count = 0
        total_amount = 0
        freight = 10

        if not user.default_address:
            user.default_address_id=0

        for index, sku_id in enumerate(selected_skus):
            sku = SKU.objects.get(id=sku_id)
            price = float(sku.price)
            count = int(redis_client.hget('cart_%s' % user.id, sku_id))
            sku_data = {
                'index': index + 1,
                'name': sku.name,
                'image_url': sku.default_image_url.url,
                'price': "%.02f" % price,
                'count': count,
                'amount': "%.02f" % (price * count)
            }
            sku_list.append(sku_data)

            total_count += count
            total_amount += price * count

        context = {
            'addresses': addresses,
            'default_address_id': user.default_address_id,
            'sku_list': sku_list,
            'total_count': total_count,
            'total_amount': "%.02f" % total_amount,
            'freight': '%.02f' % freight,
            'payment_amount': '%.02f' % (freight + total_amount)
        }

        return render(request, 'place_order.html', context=context)


class OrderCommitView(View):
    def post(self, request):

        # 验证登录状态
        if not request.user.is_authenticated:
            return JsonResponse({'code': 4101})

        # 获取数据
        address_id = json.loads(request.body.decode()).get('address_id')
        pay_method = json.loads(request.body.decode()).get('pay_method')

        # 校验数据
        if not all([address_id, pay_method]):
            return JsonResponse({'code': 9999}, status=status.HTTP_400_BAD_REQUEST)

        try:
            address = Address.objects.get(id=address_id)
        except:
            return JsonResponse({'code': 9999, 'errmsg': 'error address'}, status=400)

        if pay_method not in OrderInfo.PAY_METHODS_ENUM.values():
            return JsonResponse({'code': 9999, 'errmsg': 'error pay method'}, status=400)

        user = request.user

        redis_client = get_redis_connection('carts')
        selected_sku_id = redis_client.smembers('selected_%s' % user.id)

        if len(selected_sku_id) == 0:
            return JsonResponse({'code': 9999, 'errmsg': 'No goods is selected'}, status=400)

        for sku_id in selected_sku_id:
            if redis_client.hget('cart_%s' % user.id, sku_id) == 0:
                return JsonResponse({'code': 9999, 'errmsg': 'count should be larger than 0'}, status=400)

        # 生成订单
        order_id = "%s%09d" % (timezone.localtime().strftime('%Y%m%d%H%M%S'), user.id)

        new_order = OrderInfo.objects.create(
            order_id=order_id,
            user=user,
            address=address,
            total_count=0,
            total_amount=0,
            freight=10,
            pay_method=pay_method
        )

        for sku_id in selected_sku_id:
            sku = SKU.objects.get(id=sku_id)
            order_goods = OrderGoods.objects.create(
                order=new_order,
                sku=sku,
                count=int(redis_client.hget('cart_%s' % user.id, sku_id)),
                price=float(sku.price),
            )
            new_order.total_count += order_goods.count
            new_order.total_amount += order_goods.count * order_goods.price

        new_order.save()

        redis_client.srem('selected_%s' % user.id, *selected_sku_id)
        redis_client.hdel('cart_%s' % user.id, *selected_sku_id)

        res = {
            'code': 0,
            'errmsg': 'OK',
            'order_id': new_order.order_id
        }
        return JsonResponse(res, status=201)


class OrderSuccessView(LoginRequiredMixin, View):
    def get(self, request):
        order_id = request.GET.get('order_id')
        payment_amount = request.GET.get('payment_amount')
        pay_method = request.GET.get('pay_method')

        return render(request, 'order_success.html')
